package main.java.common;

import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import main.java.ERMDE.controllers.IProjectController;
import main.java.ERMDE.models.ProjectType;


public class ProjectTreeView {
    
    private IProjectController projectController;
    private JTree tree;
    private JPopupMenu treeMenu;
    private JMenuItem showDiagram;
    private Point lastPopupPosition;
    private JMenuItem editDiagram;
    
    
    public ProjectTreeView (JTree tree){
	
	this.tree = tree;
	this.treeMenu = new JPopupMenu();
	this.showDiagram = new JMenuItem("Show");
	this.editDiagram = new JMenuItem("EditName");
	this.lastPopupPosition = new Point(0, 0);
	this.treeMenu.add(this.showDiagram);
	this.treeMenu.add(this.editDiagram);
	
    }
  
    public void initializeTree() {
        this.tree.addMouseListener(new MouseAdapter() {
    	    @Override
    	    public void mousePressed(MouseEvent e) {
    		TreePath path = tree.getPathForLocation(e.getX(), e.getY());
    		if (path == null)
    		    return;
    		if (e.getClickCount() == 2) {
    		    boolean isLeaf = false;
      		    if (projectController.getProjectType() == ProjectType.Finite_State_Machine) {
    			boolean isActive = false;
    			for (Object o : path.getPath()) {
    			    if (o instanceof DefaultMutableTreeNode) {
    				if (((DefaultMutableTreeNode) o).isLeaf())
    				    isLeaf = true;
    			    }
    			    if (o instanceof main.java.FSMDE.infrastructure.visual.DiagramTreeNode) {
    				isActive = false;
    				main.java.FSMDE.infrastructure.visual.DiagramTreeNode node = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) o;
    				main.java.FSMDE.models.Diagram selectedDiagram = (main.java.FSMDE.models.Diagram) node
    					.getUserObject();
    				if (selectedDiagram.getId() == projectController
    					.getFsmContext()
    					.getDeppestContextDiagram().getId()) {
    				    isActive = true; // Double-click was made on
    						     // the current diagram
    				}
    			    }
    			}
    			if (isLeaf && !isActive) {
    			    JOptionPane.showMessageDialog(
    					    null,
    					    "The element you are trying to see doesn't belong to the current diagram.",
    					    "Out of bounds element",
    					    JOptionPane.WARNING_MESSAGE);
    			    return;
    			}
    			if (!isActive) {
    			    return;
    			}
    
    		    }
    		    // exception for FSM diagrams double-click ended
    		    projectController.changeElement(path);
    		} else if ((e.getButton() == MouseEvent.BUTTON3)
    			&& (projectController.getProjectType() == ProjectType.Finite_State_Machine)) {
    		    if (projectController.treeNodeIsDiagram(path)) {
    			lastPopupPosition.setLocation(e.getX(), e.getY());
    			treeMenu.show(e.getComponent(), e.getX(), e.getY());
    		    }
    		}
    	    }
    	});
        
	this.tree.addKeyListener(new KeyAdapter() {
	    @Override
	    public void keyPressed(KeyEvent e) {
		TreePath path = tree.getSelectionPath();

		switch (e.getKeyCode()) {
		case KeyEvent.VK_DELETE:
		    projectController.deleteElement(path);
		    break;
		case KeyEvent.VK_ENTER:
		    projectController.changeElement(path);
		    break;
		default:
		    break;
		}
	    }
	});
    }
    
    public void initializeShowDiagram(){
	this.showDiagram.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mousePressed(MouseEvent e) {
		TreePath path = tree.getPathForLocation(lastPopupPosition.x,
			lastPopupPosition.y);
		projectController.changeElement(path);
	    }
	});
    }	
    
    public void initializeEditDiagram(){
	this.editDiagram.addMouseListener(new MouseAdapter() {
	    @Override
	    public void mousePressed(MouseEvent e) {
		TreePath path = tree.getPathForLocation(lastPopupPosition.x,
			lastPopupPosition.y);
		// edit Diagram Name - popup dialog
		main.java.FSMDE.infrastructure.visual.DiagramTreeNode node = (main.java.FSMDE.infrastructure.visual.DiagramTreeNode) path
			.getLastPathComponent();
		main.java.FSMDE.models.Diagram currentDiagram = (main.java.FSMDE.models.Diagram) node
			.getUserObject();
		if (currentDiagram.getName().equals("Principal")) {
		    JOptionPane.showMessageDialog(null,
			    "Principal diagram name can not be edited.",
			    "Updating Principal name Error",
			    JOptionPane.ERROR_MESSAGE);
		    return;
		}
		String editedName = JOptionPane.showInputDialog(null,
			"Provide the diagram's name", currentDiagram.getName());
		if (editedName != null && !editedName.equals("")
			&& !editedName.equals(currentDiagram.getName())) {
		    // new name: Update diagram files and references
		    projectController.updateDiagramName(path, editedName);
		}
	    }
	});
	
    }

    public void setController(IProjectController projectController) {
	this.projectController = projectController;	
    }	
  
    

}
